const mysql = require('./../db');
const { generatorToken, verifyToken } = require('./../utils/token');

const {
  GraphQLString,
  GraphQLInt,
  GraphQLObjectType,
  GraphQLList,
  GraphQLSchema,
  GraphQLID,
  GraphQLNonNull,
  GraphQLInputObjectType,
  GraphQLEnumType,
  GraphQLUnionType,
  GraphQLError,
} = require('graphql');

// 第一步: 根据数据库数据库表已经有的字段定义可供前端可以查询的字段
const AccountSchema = new GraphQLObjectType({
  name: 'account',
  fields: {
    id: {
      type: GraphQLID,
    },
    username: {
      type: GraphQLString,
    },
    password: {
      type: GraphQLString,
    },
    created_at: {
      type: GraphQLString,
    },
    updated_at: {
      type: GraphQLString,
    }
  }
});

// 定义登录后的返回类型
const LoginResSchema = new GraphQLObjectType({
  name: 'loginRes',
  fields: {
    code: {
      type: GraphQLInt,
    },
    message: {
      type: GraphQLString,
    },
    token: {
      type: GraphQLString,
    }
  }
})

// 定义新增，修改，删除的返回类型
const MutationRes = new GraphQLObjectType({
  name: 'mutationRes',
  fields: {
    code: {
      type: GraphQLNonNull(GraphQLInt),
    },
    message: {
      type: GraphQLString,
    },
  }
})

const SearchResHandler = (type) => {
  return new GraphQLUnionType({
    name: 'searchRes',
    types: [type, MutationRes],
  })
}
// const accountListRes = new GraphQLUnionType({
//   name: 'xx',
//   fields: [GraphQLList(AccountSchema), MutationRes],
//   resolveType(value) {
//     console.log(value);
//     if (Array.isArray(value)) {
//       return [GraphQLList(AccountSchema)];
//     } else {
//       return MutationRes;
//     }
//   }
// })
const RootSchema = new GraphQLObjectType({
  name: 'root',
  fields: {
    // 查询列表出来
    accountList: {
      type: GraphQLList(AccountSchema),
      async resolve (parent, args, context) {
        console.log(parent, '====方法==>,',context)
        if (parent.token) {
          // 反解出用户信息
          try {
            const data = await verifyToken(parent.token);
            console.log(data, '用户信息');
            const result = await mysql.query('select id, username, password,created_at, updated_at from account');
            return result;
          } catch(e) {
            return new GraphQLError(JSON.stringify({
              code: 10024,
              message: 'token解析错误',
            }));
          }
        } else {
          return new GraphQLError(JSON.stringify({
            code: 10024,
            message: '请先登录'
          }));
        }
      }
    },
    // 根据id查询出一条数据
    account: {
      type: AccountSchema,
      args: { id: { type: GraphQLID } },
      async resolve (parent, args) {
        console.log(args, '参数')
        const result = await mysql.query('select id, username, password,created_at, updated_at from account where id = ?', [args.id]);
        return result[0];
      }
    },
    // 用户登录
    login: {
      type: LoginResSchema,
      args: {
        username: {
          type: new GraphQLNonNull(GraphQLString),
        },
        password: {
          type: new GraphQLNonNull(GraphQLString),
        },
      },
      async resolve (parent, args) {
        console.log(parent, '======>')
        const username = args.username;
        const password = args.password;
        console.log(args, 'args')
        const result = await mysql.query('select * from account where username =? and password = ?', [username, password]);
        console.log(result[0], '登录结果')
        if (result && result.length) {
          return {
            code: 0,
            message: '登录成功',
            token: generatorToken(result[0]),
          };
        } else {
          return {
            code: 1,
            message: '用户名或密码错误',
            token: '',
          };
        }
      }
    }
  }
})

const updateAccountType = new GraphQLInputObjectType({
  name: 'updateAccount',
  fields: {
    username: {
      type: GraphQLString,
    },
    password: {
      type: GraphQLString,
    }
  }
})
// 定义mutation对数据的增删改操作
const MutationSchema = new GraphQLObjectType({
  name: 'mutation',
  fields: {
    addAccount: {
      type: MutationRes,
      args: {
        username: {
          type: new GraphQLNonNull(GraphQLString),
        },
        password: {
          type: new GraphQLNonNull(GraphQLString),
        }
      },
      async resolve (parent, args) {
        const username = args.username;
        const password = args.password;
        const result = await mysql.query('insert into account(username, password) values(?,?)', [username, password]);
        console.log(result, '插入数据');
        if (result && result.affectedRows) {
          return {
            code: 0,
            message: '插入成功'
          };
        } else {
          return {
            code: 1,
            message: '插入失败'
          };
        }
      }
    },
    // 根据id删除数据
    deleteAccountById: {
      type: MutationRes,
      args: {
        id: {
          type: new GraphQLNonNull(GraphQLID)
        }
      },
      async resolve (parent, args) {
        const result = await mysql.query('delete from account where id = ?', [args.id]);
        if (result.affectedRows) {
          return {
            code: 0,
            message: '删除成功'
          };
        } else {
          return {
            code: 0,
            message: '删除失败'
          };
        }
      }
    },
    // 根据id修改数据
    modifyAccountById: {
      type: MutationRes,
      args: {
        id: {
          type: new GraphQLNonNull(GraphQLID)
        },
        data: {
          type: updateAccountType,
        }
      },
      async resolve (parent, args) {
        const id = args.id;
        const username = args.data.username;
        const password = args.data.password;
        const result = await mysql.query('update account set username = ?, password = ? where id = ?', [username, password, id]);
        if (result && result.affectedRows) {
          return {
            code: 0,
            message: '修改成功'
          };
        } else {
          return {
            code: 0,
            message: '修改失败'
          };
        }
      },
    },
  }
})


module.exports = new GraphQLSchema({
  query: RootSchema,
  mutation: MutationSchema,
})